package com.timedomain.him.remake.views;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Handler;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

import org.jetbrains.annotations.Nullable;


public class NumericUpAndDown extends View {
    public NumericUpAndDown(Context context) {
        super(context);
        initPaint();
    }

    public NumericUpAndDown(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();

    }

    public NumericUpAndDown(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();

    }

    public NumericUpAndDown(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initPaint();

    }

    private boolean hasMoreAnim = false;

    private void initPaint(){
        fontBoxSize = dp2pix(60);
        textPaint = new TextPaint();
        textPaint.setTextSize(dp2pix(21));
        textPaint.setColor(Color.argb(255,133,133,133));
        textPaint.setTypeface(Typeface.SERIF);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setAntiAlias(true);
        darkerTextPaint = new TextPaint(textPaint);
        darkerTextPaint.setColor(Color.argb(128,133,133,133));
        calculateOffsetAndMaxOffset();
        smoothedOffsetValue = offsetValue;
    }

    TextPaint textPaint = null;
    TextPaint darkerTextPaint = null;

    @Override
    protected void onDraw(Canvas canvas) {
        float textHeight = textPaint.measureText("啊");
        float drawY = getHeight() / 2f + textHeight / 2f;
        float centerX = getWidth() / 2f;
        for (int i = 0; i <= maxValue; i++) {
            float drawX = centerX + fontBoxSize * i - smoothedOffsetValue;

            if(Math.abs(drawX - centerX) < fontBoxSize / 2){

                canvas.drawText(""+i,drawX,drawY,textPaint);
            }
            else{

                canvas.drawText(""+i,drawX,drawY,darkerTextPaint);
            }
        }
        smoothedOffsetValue = smoothedOffsetValue + (offsetValue - smoothedOffsetValue) * 0.2f;

        if(Math.abs(smoothedOffsetValue - offsetValue) < 0.00001){
            hasMoreAnim = false;
        }else if(Math.abs(smoothedOffsetValue - offsetValue) < 0.001){
            smoothedOffsetValue = offsetValue;
        }
    }


    @FunctionalInterface
    public interface UserChangedValueListener {
        void onChanged(NumericUpAndDown view,int newValue);
    }

    public void setUserChangedValueListener(@Nullable UserChangedValueListener listener){
        this.mUserChangedValueListener = listener;
    }

    private UserChangedValueListener mUserChangedValueListener = null;


    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
        calculateOffsetAndMaxOffset();
        notifyAnim();
    }

    public int getMaxValue() {
        return maxValue;
    }

    public void setMaxValue(int maxValue) {
        this.maxValue = maxValue;
        if(value > maxValue){value = maxValue;}
        calculateOffsetAndMaxOffset();
        notifyAnim();
    }

    private void calculateOffsetAndMaxOffset(){
        if(!isPressedDown){

            offsetValue = value * fontBoxSize;
            maxOffset = maxValue * fontBoxSize;
        }
        notifyAnim();
    }

    private void notifyAnim(){
        hasMoreAnim = true;
        handler.post(runAnim);
    }

    Handler handler = new android.os.Handler();
    Runnable runAnim = new Runnable() {
        @Override
        public void run() {
            if(hasMoreAnim || isPressedDown){
                invalidate();
                handler.postDelayed(runAnim,16);
            }
        }
    };

    private int value = 30;

    private int maxValue = 30;

    private float fontBoxSize = 0;

    private float offsetValue = 0;
    private float smoothedOffsetValue = 0;

    private float maxOffset = 1;

    private boolean isPressedDown = false;
    private float pressedX = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if(event.getAction() == MotionEvent.ACTION_DOWN){
            isPressedDown = true;
            notifyAnim();
            pressedX = event.getX();
        }
        if(event.getAction() == MotionEvent.ACTION_MOVE){
            offsetValue -= (event.getX() - pressedX);
            if(offsetValue < 0){
                offsetValue = 0;
            }
            if(offsetValue >=maxOffset){
                offsetValue = maxOffset;
            }
            pressedX = event.getX();
        }
        if(event.getAction() == MotionEvent.ACTION_UP){
            isPressedDown = false;
            notifyAnim();
            this.value = (int) Math.round(offsetValue / fontBoxSize);
            if(value < 0){
                value = 0;
            }
            if(value >maxValue){
                value = maxValue;
            }
            this.setValue(this.value);
            if(mUserChangedValueListener != null){
                mUserChangedValueListener.onChanged(this,value);
            }
        }


        return true;
    }
    private float dp2pix(float dp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
    }
}
